﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Lidgren.Network;
using Lidgren.Network.Xna;
using SharedLib.Network.Server;
using SharedLib.Network.Client;

namespace SharedLib.Engine
{

    public enum EntitySide
    {
        Client,
        Server
    }

    public enum EntityType
    {
        Entity,
        Creature,
        Monster,
        Player,
        Light
    }

    public enum EntityState
    {
        Alive,
        Dead
    }

    public class Entity
    {
        public long ID;
        public string Name;

        public bool Selectable = false;

        public EntitySide Side = EntitySide.Server;

        private Vector2 _position;
        
        public Vector2 Position
        {
            get 
            { 
                return _position; 
            }
            set 
            {

                Point beforeMove = getChunkPosition();

                this._position = value;

                Point afterMove = getChunkPosition();

                if (Side == EntitySide.Server)
                {
                    if (beforeMove != afterMove)
                    {
                        if (this.Type == EntityType.Player)
                            Server.Instance.ServerSender.SendPlayerChunk((ServerPlayer)this);

                        Server.Instance.ServerSender.SendEntityLeft(this);

                        ServerChunk oldChunk = Server.Instance.GameWorld.Chunks.Where(c => c.X == beforeMove.X && c.Y == beforeMove.Y).FirstOrDefault();
                        if (oldChunk != null)
                            oldChunk.Entities.Remove(this);

                        ServerChunk currentChunk = Server.Instance.GameWorld.Chunks.Where(c => c.X == afterMove.X && c.Y == afterMove.Y).FirstOrDefault();
                        if (currentChunk != null)
                            currentChunk.Entities.Add(this);


                        this.ChunkPosition = afterMove;
                        Server.Instance.ServerSender.SendEntityJoined(this);

                    }
                    Server.Instance.ServerSender.SendMovementUpdate(this);
                }

            }
        }
        


        public Vector2 Velocity = Vector2.Zero;

        private Point _chunkPosition;

        public Point getChunkPosition()
        {
           
                int chunkX = (int)(this.Position.X / Constants.TILE_SIZE / Constants.CHUNK_WIDTH) - (this.Position.X < 0 ? 1 : 0);
                int chunkY = (int)(this.Position.Y / Constants.TILE_SIZE / Constants.CHUNK_HEIGHT) - (this.Position.Y < 0 ? 1 : 0);
                return new Point(chunkX, chunkY);
                
        }
        

        public Point ChunkPosition = Point.Zero;

        public EntityType Type = EntityType.Entity;
        public EntityState State = EntityState.Alive;


        public Entity Target = null;

        private float _rotation;

        public float Rotation
        {
            get { return _rotation; }
            set 
            { 
                _rotation = value;
                if (Side == EntitySide.Server)
                {
                    Server.Instance.ServerSender.SendRotationUpdate(this);
                }
               
            }
        }
        

     //   public float Rotation = 0f;
        
        public Entity()
        {
            this.Selectable = true;
        }

        

        public virtual void Update(long time)
        {
        }

        public virtual void Update(GameTime gameTime)
        {
        }

        public virtual void WriteData(NetOutgoingMessage outmsg)
        {
            outmsg.Write((byte)Type);
        }

        public virtual void ReadData(NetIncomingMessage _msgBuffer)
        {
            
        }
    }
}
